package network.byteConversions;
import java.util.Map;
import java.util.TreeMap;

import tools.Help;
import tools.Point;
public class ByteMapper {
	private class OffsetType {
		public OffsetType(char stype) {
			this.type = stype;
		}
		public char type;
		public int offset;
	}
	private TreeMap<String, OffsetType> map;
	public ByteMapper() {
		map = new TreeMap<String, OffsetType>();
	}
	private static int getTypeSize(char type) {
		switch (type) {
			case 'F' :
				return 4;
			case 'C' :
				return 1;
			case 'I' :
				return 4;
			case 'B' :
				return 1;
			case 'L' :
				return 8;
			case 'P' :
				return 8;
		}
		Help.p("No such Type: " + type);
		return 0;
	}
	public char getTypeChar(Object obj) {
		if (obj.getClass() == float.class) {
			return 'F';
		}
		else if (obj.getClass() == int.class) {
			return 'I';
		}
		else if (obj.getClass() == boolean.class) {
			return 'B';
		}
		else if (obj.getClass() == Point.class) {
			return 'P';
		}
		else if (obj.getClass() == char.class) {
			return 'C';
		}
		if (obj.getClass() == long.class) {
			return 'L';
		}
		Help.p("Not a valid type" + obj.getClass().getName());
		return '!';
	}
	private void reMapVars() {
		int offs = 0;
		for (Map.Entry<String, OffsetType> e : map.entrySet()) {
			e.getValue().offset = offs;
			offs += getTypeSize(e.getValue().type);
		}
	}
	/**
	 * Puts a var into the map and reorganizes byte offsets for all variables in the map
	 * 
	 * @param name
	 *            name of variable
	 * @param obj
	 *            object to map (must be float,int,boolean,long,Point)
	 */
	public void mapVar(String name, char vtype) {
		if (isValidType(vtype)) {
			map.put(name, new OffsetType(vtype));
			reMapVars();
		}
	}
	private boolean isValidType(char vtype) {
		if (vtype == 'F' || vtype == 'I' || vtype == 'C' || vtype == 'P' || vtype == 'B' || vtype == 'L')
			return true;
		return false;
	}
	public int getOffset(String varname) {
		OffsetType ot = map.get(varname);
		return ot.offset;
	}
	public int getTotalSize() {
		return map.lastEntry().getValue().offset + getTypeSize(map.lastEntry().getValue().type);
	}
	public int getSizeOf(String vname) {
		OffsetType ot = map.get(vname);
		return getTypeSize(ot.type);
	}
}
